<template>
  <div class="home">
    <div class="title">
      测试移动端兼容 .postcssrc.js配置文件
      https://blog.csdn.net/weixin_45633478/article/details/123232655
    </div>

    <h1 @click="toNoRet">不需要return的页面</h1>

    <h1>父传子 子传父 {{ arr1 }} {{ arr2 }}</h1>

    <!--  获取焦点阴影加重  -->
    <input class="ipt" type="text" v-model="states.value" name="" id="" />
    <p>{{ states.getnum }}</p>
    <nav-Headers
      @changeval="changevals"
      :numActive="states.value"
      :utilss="utilss"
    /><!-- 父传子 子传父  -->

    <h1 @click="routerAbout">跳转about</h1>

    <p @click="about">跳转about</p>
    <h1>component API ref</h1>
    <p>{{ count }}</p>
    <h2>ref操作数据</h2>

    <p ref="changename">张三</p>
    <p @click="changeName">修改名字</p>

    <h2>ref操作组件</h2>
    <falater ref="falatername"></falater>
    <p @click="upname">修改falater</p>
    <h2>ref操作循环数据</h2>

    <ul>
      <!-- componentAPI el是这个li list[index] 赋值这个el-->
      <li
        v-for="(item, index) of userlist"
        :key="index"
        :ref="
          (el) => {
            if (el) list.push(el);
          }
        "
      >
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>

<script>
import navHeaders from "../components/Home/navHeaders.vue";
import falater from "../components/Home/falater.vue";
import router from "@/router/index.js";

import {
  Vue,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onActivated,
  onDeactivated,
  onErrorCaptured,
  onRenderTracked,
  onRenderTriggered,
  watchEffect,
  watch,
  getCurrentInstance,
  ref,
  computed,
  toRef,
  toRefs,
  unref,
  isRef,
  inject,
  provide,
  reactive,
  readonly,
} from "vue";
import { useRouter } from "vue-router";

export default {
  components: {
    navHeaders,
    falater,
  },
  name: "Home",

  data() {
    return {
      name: "provide inject",
    };
  },

  mounted() {
    this.name = "list";
  },
  setup(props, ctx) {
    const arr1 = ref("数组一");
    const arr2 = ref("数组二");
    const count = ref(200);
    const otherCount = ref(21);
    const refce = ref(21);

    const states = reactive({
      userlist: [
        { name: "张", age: 18 },
        { name: "李", age: 19 },
        { name: "王", age: 20 },
      ],
      Array: [arr1, arr2],
      count, //ref可以写在reactiv里面
      value: 17,
      num: 5,
      ach: 10,
      getnum: 10,
      obj: {
        a: {
          name: "更改前的name",
        },
        b: {
          age: 18,
        },
        c: {
          name: "Mr张",
        },
      },
    });

    // provide
    let myName = ref(states.obj.c.name);
    let provideName = ref(states.value);
    let provideAge = "280";
    let provideHeight = "180";

    const providechangeName = (e) => {
      provideName.value++;
    };
    provide("myName", myName);

    provide("name", provideName);
    provide("age", provideAge);
    provide("height", provideHeight);
    provide("providechangeName", providechangeName);

    let utilss = {
      a: 1,
      b: 2,
    };

    // 父接受子
    const changevals = (val) => {
      // console.log(val)
      provideName.value++;
      states.getnum = val;
      // console.log(val);
    };

    // 跳转无renturn页面
    let toNoRet = () => {
      router
        .push({
          name: "noRet",
          params: {
            id: 1,
            name: "noRet",
          },
        })
        .catch((err) => {
          // console.log(err)
        });
    };
    let about = () => {
      //跳转路由
      router
        .push({
          name: "about",
          params: {
            id: 1,
            name: "xiaoming",
          },
        })
        .catch((err) => {
          // console.log(err)
        });
    };

    states.count = otherCount; //更改的 count 不能改变原来的值
    // console.log(states.Array[1].value) //ref中的写在reactive中根据下标.value 取值

    setTimeout(() => {
      console.log(758);
      count.value++;
      // states.obj.a.name ="更改后的name"
      // states.obj.b.age ="更改后20"
      states.obj.b.age++;
      states.num++;
      states.value++;
      states.ach++;
      otherCount.value++;
    }, 2000);

    // setTimeout(()=>{
    //   states.value++;
    //   count.value ++
    // },3000)

    const newReactive = readonly(states); //只能获取不能更改

    // watch属性

    // ref这样监听
    // watch(count,(a,b,onInvalidate)=>{
    //   console.log(a,b)
    //   onInvalidate(() =>{
    //     console.log('onInvalidate')
    //   })
    // })

    // ref也可以这样监听
    // watch(() => count.value,(a,b) => {
    // console.log(a,b)
    // })

    // watch(() => states.obj,(a,b) => {
    // console.log(a,b)
    // },{deep:true}
    // );

    // raactive这样监听
    // watch(() => states.num,(a,b) => { //reactive 中监听某个属性 数据源必须精确指定
    //   console.log(a,b)
    // });

    //  watch(()=>[states.value,states.num,states.ach], //多个数据监听
    //           ([newnum, oldnum,newach],[newvalue, oldvalue,oldach])=>{
    //             // 新数据
    //             console.log(newnum)
    //             console.log(oldnum)
    //             console.log(newach)
    //             // 老数据
    //             console.log(newvalue)
    //             console.log(oldvalue)
    //             console.log(oldach)
    //       },{
    //         flush:'post'
    //       });
    // watch没有flush:'post'在watch之后 有在之前
    // onBeforeUpdate(()=>{
    // console.log('onBeforeUpdate')
    // })

    // 监听一段时间不监听
    // var stop = watch(() => states.num,(a,b) => { //reactive 中监听某个属性 数据源必须精确指定
    //   console.log(a,b)
    // });
    // setTimeout(()=>{
    //   stop()
    // },2000)

    // toRef ,toRefs ,isRef ,unref属性
    // toRef:转化为ref
    const torNum = toRef(states, "num");
    console.log(torNum.value); //5

    // isRef 判断是否为ref对象
    const info = ref({ name: "名字", info: { age: 18, height: 1111 } });
    const infos = { name: "名字", info: { age: 18, height: 1111 } };
    console.log(isRef(info)); // true
    console.log(isRef(infos)); // false

    console.log(unref(info)); // Proxy {name: '名字', info: {…}}
    console.log(unref(infos)); //       {name: '名字', info: {…}}

    // isRef(info)?info.value:'info'  等同unref(info)
    //toRefs 数据return 出去 ...toRefs()

    //component
    // 在元素上使用
    const changename = ref(null); //dom节点绑定 ref = changename事件设置的值
    const changeName = () => {
      // console.log(changename.value.innerText)
      changename.value.innerText = "李思思";
    };
    // // 在组件中使用 等于调用组件中的方法
    const falatername = ref(null);
    const upname = () => {
      falatername.value.upname();
    };

    const list = ref([]);
    onMounted(() => {
      console.log(useRouter().options.routes);

      // console.log(list)
      // console.log(list.value[0])
    });

    // onBeforeMount(() => {
    //   console.log("onBeforeMount-->beforeMount 模板渲染未挂载到页面中去");
    // });

    // onMounted(() => {
    //   console.log("onMounted-->mounted 真实dom已经生成");
    // });

    // onBeforeUpdate(() => {
    //   console.log("onBeforeUpdate-->beforeUpdate 数据更新之前");
    // });

    // onUpdated(() => {
    //   console.log("onUpdated-->updated 数据更新之后");
    // });

    // onBeforeUnmount(() => {
    //   console.log("onBeforeUnmount-->beforeDestroy 页面销毁前");
    // });

    // onUnmounted(() => {
    //   console.log("onUnmounted-->destroyed 页面销毁后");
    // });

    // 被包含在<keep-alive>中的组件，会多出两个生命周期钩子函数
    // onActivated(() => {
    //   console.log("onActivated-->activited keep-alive 缓存的组件激活时调用");
    // });

    // onDeactivated(() => {
    //   console.log("onDeactivated-->deactivated keep-alive 缓存的组件停用时调用");
    // });

    // onErrorCaptured(() => {
    //   console.log("onErrorCaptured-->errorCaptured 当捕获一个来自子孙组件的异常时激活钩子函数");
    // });

    // // 调试用
    // onRenderTracked(() => {
    //   console.log("onRenderTracked 状态跟踪，它会跟踪页面上所有响应式变量和方法的状态，也就是我们用return返回去的值，他都会跟踪。只要页面有update的情况，他就会跟踪，然后生成一个event对象，我们通过event对象来查找程序的问题所在");
    // });

    // onRenderTriggered(() => {
    //   console.log("onRenderTriggered 状态触发,它不会跟踪每一个值，而是给你变化值的信息，并且新值和旧值都会给你明确的展示出来");
    // });

    // watchEffect 属性
    // watchEffect(()=>{ //页面进入时执行一次 数据变化时执行
    //   var a = states.value
    //   console.log('watchEffect')
    // },{
    //   flush:'post' //添加flush:'post'会在onBeforeUpdate之后执行 没有会在之前
    // })

    //  var stop =  watchEffect(async (onInvalidate)=>{
    //   var a = states.value
    //   console.log('watchEffect')
    //   onInvalidate(()=>{ //没有stop先执行回调 在执行副作用
    //       console.log("onInvalidate") //有stop 执行会停在这里 副作用不在执行
    //   })
    // })
    // setTimeout(()=>{
    //   stop()
    // },2000)

    // onMounted(()=>{
    //   watchEffect(()=>{
    //     console.log("f")
    //   })
    // })

    // watchEffect(()=>{
    //   console.log(states.value)
    // },{
    //   onTrack(e){//第一次执行 当依赖改变也执行
    //   // debugger
    //     console.log('onTrack',e)

    //   },
    //   onRrigger(e){ //当依赖改变执行
    //     console.log('onRrigger',e)
    //   }
    // }
    // )

    // computed属性
    // const supercomputed = computed(()=>{
    //     return 'computed属性'+states.value
    // })
    //     console.log(supercomputed.value)
    // const supercomputed = computed({
    //   get (){
    //     console.log('get属性'+states.value)
    //     return 'get属性'+states.value
    //   },
    //   set(){
    //     console.log('set属性'+states.value)
    //   }
    // })
    // supercomputed.value = 2 //一般不再computed中写set
    // console.log(supercomputed.value)

    return {
      count, //返回的count 还是ref老的值
      arr1,
      arr2,
      states,
      refce,
      changevals,
      about,
      toNoRet,
      utilss,
      changeName,
      changename,
      falatername,
      upname,
      list,
      ...toRefs(states),
    };
  },
};
</script>
<style scoped>
.title {
  overflow: hidden;
  width: 100px;
}

/* 获取焦点阴影加重 */
.ipt {
  box-shadow: 0 0 10px #000;
  transition: box-shadow 1s;
}
.ipt:focus-within {
  box-shadow: 0 0 10px red;
}
</style>
